package org.jeecg.modules.meter.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SsoUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.entity.meter.*;
import org.jeecg.enums.car.CarSyncStatusEnum;
import org.jeecg.enums.PayStatusEnum;
import org.jeecg.enums.meter.*;
import org.jeecg.modules.meter.entity.MeterRoom;
import org.jeecg.modules.meter.iot.entity.MeterBaseDto;
import org.jeecg.modules.meter.iot.entity.MeterCollectInfoDto;
import org.jeecg.modules.meter.service.*;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecg.vo.meter.*;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description: 水电表基础信息
 * @Author: jeecg-boot
 * @Date: 2019-12-05
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "水电表基础信息")
@RestController
@RequestMapping("b/meter/base")
public class MeterController {
    @Autowired
    private IMeterChargeInfoService meterChargeInfoService;
    @Autowired
    private IMeterFeeRuleService meterFeeRuleService;
    @Autowired
    private IMeterChangeInfoService changeInfoService;
    @Autowired
    private IMeterService meterService;
    @Autowired
    private IMeterGatewayService meterGatewayService;
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    @Autowired
    private MeterIotService meterIotService;
    @Autowired
    private IMeterRoomService meterRoomService;
    @Autowired
    private IMeterFeeService meterFeeService;
    @Autowired
    private IMeterAccountService meterAccountService;
    @Autowired
    private IMeterReadService meterReadService;
    @Autowired
    private IMeterControlSwitchService meterControlSwitchService;
    /**
     * 分页列表查询
     *
     * @param meter
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "水电表基础信息-分页列表查询")
    @ApiOperation(value = "水电表基础信息-分页列表查询", notes = "水电表基础信息-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<Meter>> list(Meter meter,
                                     @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                     HttpServletRequest req) {
        Result<IPage<Meter>> result = new Result<>();
        /*if (StringUtils.isNotEmpty(meter.getDepartType())){
            if (meter.getDepartType().equals("project")){
                meter.setProjectId(meter.getDepartIdEx());
            }
        }*/
        meter.setSqlMap(sysUserRoleService.dataScopeProjectOnlyFilter(SsoUtil.getLoginUser(), "p", meter.getMenuPath(), null, meter.getDepartIdEx()));
        meter.setTenantId(SsoUtil.getLoginUser().getTenantId());
        Page<Meter> page = new Page<>(pageNo, pageSize);
        List<Meter> list = meterService.findPage(page, meter);
        page.setRecords(list);
        result.setSuccess(true);
        result.setResult(page);
        return result;
    }

    /**
     * 获取项目收费项
     *
     * @Param projectId
     */
    @GetMapping("getMeterFeeRule")
    public Result<List<MeterFeeRule>> getMeterFeeRule(@RequestParam(name = "projectId") String projectId) {
        Result<List<MeterFeeRule>> result = new Result<>();
        List<MeterFeeRule> meterFeeRuleList = meterFeeRuleService.getMeterFeeRule(projectId);
        result.setResult(meterFeeRuleList);
        result.setSuccess(true);
        return result;
    }
    /**
     * add
     */
    @RequestMapping("add")
    public Result<?> add(@RequestBody Map<String, Object> map) {
        Result<?> result = new Result<>();
        if (map.isEmpty()) {
            return Result.error("系统内部错误");
        }
        Meter meter = JSON.parseObject(JSON.toJSONString(map), Meter.class);
        //校验网关
        Integer count = meterGatewayService.queryCountByWayNo(meter.getMeterCode(), meter.getMeterGateway());
        if (count > 0) {
            result.setMessage("同一网关下设备号唯一！");
            result.setSuccess(false);
            return result;
        }
        //获取公司ID
        String tenantId = meterService.queryTenantId(meter.getProjectId());
        meter.setTenantId(tenantId);
        meterService.save(meter);
        String MeterId = meter.getId();
        //绑定收费房间 测试测试
        ArrayList<MeterRoom> meterRooms = new ArrayList<>();
       if (meter.getFloorIdList() !=null ){
           if (meter.getFloorIdList().size() > 0) {
               for (int a = 0; a < meter.getFloorIdList().size(); a++) {
                   MeterRoom meterRoom = new MeterRoom();
                   meterRoom.setProjectId(meter.getProjectId());
                   meterRoom.setMeterId(MeterId);
                   meterRoom.setIsBind(MeterBindStatusEnum.METER_BIND_STATUS_YES.getCode());
                   meterRoom.setRoomId(meter.getRoomIdList().get(a));
                   meterRoom.setBuildingId(meter.getFloorIdList().get(a));
                   meterRooms.add(meterRoom);
               }
           }
       } else {
           MeterRoom meterRoom = new MeterRoom();
           meterRoom.setProjectId(meter.getProjectId());
           meterRoom.setMeterId(MeterId);
           meterRoom.setIsBind(MeterBindStatusEnum.METER_BIND_STATUS_YES.getCode());
           meterRooms.add(meterRoom);
       }
        if (meterRooms.size() > 0) {
            meterRoomService.saveBatch(meterRooms);
        }
        //绑定收费项
        ArrayList<MeterFee> meterFeeList = new ArrayList<>();
        if (meter.getPayItem()!=null) {
            for (String meterFeeRuleId : meter.getPayItem()) {
                MeterFee meterFee = new MeterFee();
                meterFee.setTenantId(tenantId);
                meterFee.setMeterId(MeterId);
                meterFee.setFeeRuleId(meterFeeRuleId);
                meterFee.setProjectId(meter.getProjectId());
                meterFee.setIsBind(MeterBindStatusEnum.METER_BIND_STATUS_YES.getCode());
                meterFeeList.add(meterFee);
            }
            meterFeeService.saveBatch(meterFeeList);
        }
        MeterAccount meterAccount = new MeterAccount();
        meterAccount.setMeterId(meter.getId());
        meterAccount.setTotalUse("0");  //初始时
        meterAccount.setPayAmount("0");
        meterAccount.setTenantId(tenantId);
        meterAccount.setRemainAmount(meter.getBeginAmount());
        meterAccount.setRemainUse(meter.getBeginUse());
        boolean save = meterAccountService.save(meterAccount);
        if (save) {
            result.setMessage("新增成功");
            result.setSuccess(true);
        } else {
            result.setMessage("新增失败");
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 通断
     */
    @RequestMapping("controlSwitch")
    public Result<?> controlSwitch(@RequestParam(name = "meterId") String meterId,
                                   @RequestParam(name = "state", required = true) Integer state) {
        Result<Object> result = new Result<>();
        //查询电表是否存在
        LoginUser loginUser = SsoUtil.getLoginUser();
        try {
            Meter meter = meterService.getById(meterId);
            if (meter == null) {
                return Result.error("仪表不存在,操作错误");
            }
            MeterControlSwitch mcs = new MeterControlSwitch();
            mcs.setRequestTime(new Date());
            mcs.setId(UUID.randomUUID().toString().replace("-", ""));
            boolean b = meterControlSwitchService.controlSwitchRequest(meterId, state);
            if (!b) {
                return Result.error("下发指令失败，操作失败");
            }
            Integer status = 0;
            if (state == MeterSwitchStatusEnum.METER_SWITCH_STATUS_ON.getCode()){
                status = MeterSwitchStatusEnum.METER_SWITCH_STATUS_ON_ING.getCode();
            }else {
                status =  MeterSwitchStatusEnum.METER_SWITCH_STATUS_OFF_ING.getCode();
            }
            //更新水电表状态为送电中
            meter.setSwitchStatus(status);
            meter.setCreateBy(loginUser.getRealname());
            meterService.updateSwitchStatus(meter);
            return Result.ok("操作成功");
        } catch (Exception e) {
            return Result.error("操作失败");
        }
    }

    /**
     * 费用明细
     */
    @RequestMapping("getMeterCostDetail")
    public Result<List<MeterChargeInfo>> getMeterCostDetail(@RequestParam("meterId") String meterId) {
        Result<List<MeterChargeInfo>> result = new Result<>();
        try {
            List<MeterChargeInfo> meterCostDetail = changeInfoService.getMeterCostDetail(meterId);
            for (MeterChargeInfo meterChargeInfo : meterCostDetail) {
                meterChargeInfo.setRemarks(MeterChargeTypeEnum.getDesc(meterChargeInfo.getChargeType()));
            }
            result.setResult(meterCostDetail);
            return result;
        } catch (Exception e) {
            return result.error500("系统错误");
        }
    }

    /**
     * 历史读数
     */
    @RequestMapping("historyRead")
    public Result<List<MeterRead>> historyRead(@RequestParam("meterId") String meterId) {
        Result<List<MeterRead>> result = new Result<>();
        List<MeterRead> meterReadList = meterService.historyRead(meterId);
        result.setResult(meterReadList);
        return result;
    }

    /**
     * 修改状态
     */
    @RequestMapping("updateMeterStatus")
    public Result<?> updateMeterStatus(@RequestParam(name = "meterId") String meterId,
                                       @RequestParam(name = "state") Integer state) {
        Result<Object> result = new Result<>();
        LoginUser loginUser = SsoUtil.getLoginUser();
        Meter meter = meterService.getById(meterId);
        if (null == meter) {
            return Result.error("仪表不存在");
        }
        //state --》停用 正常
        //表里数据不为正常 或为已换表
        //停用 正常 已换表
        if (!meter.getUseStatus().equals(MeterUseStatusEnum.USE_NORMAL.getCode())) {
            //表里数据不是停用
            if (!meter.getUseStatus().equals(MeterUseStatusEnum.USE_STOP.getCode()) || !state.equals(MeterUseStatusEnum.USE_NORMAL.getCode())) {
                return Result.error("当前仪表不支持状态变更");
            }
            Integer integer = meterService.updateStatus(meterId, state, loginUser);
            result.setMessage("仪表已启用");
            result.setSuccess(integer > 0 ? true : false);
        } else {
            if (state.equals(MeterUseStatusEnum.USE_STOP.getCode())) {
                Integer integer = meterService.updateStatus(meterId, state, loginUser);
                result.setMessage("仪表已停用");
                result.setSuccess(integer > 0 ? true : false);
            } else {
                result.setMessage("当前已是正常状态");
            }
        }
        return result;
    }

    /**
     * 地址列表展示
     *
     * @Param:meterId
     */
    @RequestMapping("getAddressList")
    public Result<List<ReceiveList>> getAddressList(@RequestParam("meterId") String meterId) {
        Result<List<ReceiveList>> result = new Result<>();
        List<ReceiveList> addressList = meterService.getAddressList(meterId);
        result.setResult(addressList);
        return result;
    }

    /**
     * 修复读数
     * @return
     */
    @RequestMapping("repairRead")
    public Result<?> repairRead(@RequestParam("readId") String readId,@RequestParam("preRead") BigDecimal preRead){
        MeterRead oldMeterRead =  meterReadService.getById(readId);
        if (oldMeterRead ==null) return Result.error("未取到读表记录");
        MeterChargeInfo meterChargeInfo = meterChargeInfoService.getByReadId(readId);
        if (meterChargeInfo == null) return  Result.error("未取到扣费记录");
        meterService.repairRead(oldMeterRead,meterChargeInfo,preRead);
        return Result.ok();
    }

    /**
     * 更新读数
     */
    @RequestMapping("updateRead")
    public Result<?> updateRead(@RequestParam("ids") String ids) throws ParseException {
        StringBuilder resMsg = new StringBuilder();
        if (StringUtils.isEmpty(ids)) {
            return Result.error("请选择需要更新的仪表");
        }
        List<Meter> meterList = meterService.queryMeterList(Arrays.asList(ids.split(";")));
        HashMap<String, MeterCollectReqVo> gatewayMap = new HashMap<>();
        for (Meter meter : meterList) {
            //只有状态为正常的仪表才可读数读数  正常
            if (meter.getUseStatus() != MeterStatusEnum.USE_NORMAL.getCode()) {
                resMsg.append(meter.getMeterCode()).append("状态为");
                resMsg.append(MeterUseStatusEnum.getDesc(meter.getUseStatus())).append("不可读表;");
                continue;
            }
            //同步读表
            if (meter.getSyncStatus() != CarSyncStatusEnum.SYNC_STATUS_YES.getCode()){
                resMsg.append(meter.getMeterCode()).append("非同步状态,读表失败;");
                continue;
            }
            if (StringUtils.isBlank(meter.getMeterKey())){
                resMsg.append(meter.getMeterCode()).append("仪表key不存在,请同步仪表,读表失败;");
                continue;
            }
            //获取仪表对应的收费项单价 获取有效期收费项单价
            MeterFeeRule meterFeeRule = meterFeeRuleService.queryFeeByMeterId(meter.getId());
            if (meterFeeRule == null || meterFeeRule.getFeePrice() == null ) {
                resMsg.append(meter.getMeterCode()).append("没有配置收费项或已过有效期;");
                continue;
            }
            BigDecimal price = meterFeeRule.getFeePrice();
            Integer roundMode = meterFeeRule.getRoundMode();
            Integer precision = meterFeeRule.getFeePrecision(); //计费精度
            MeterCollectReqVo meterCollectReqVo = gatewayMap.get(meter.getMeterGateway());
            if (meterCollectReqVo == null) {
                meterCollectReqVo = new MeterCollectReqVo();
                MeterGateway meterGateway = meterGatewayService.getById(meter.getMeterGateway());
                if (meterGateway != null) BeanUtils.copyProperties(meterGateway,meterCollectReqVo);
                //存储同一网关单个仪表
                gatewayMap.put(meter.getMeterGateway(), meterCollectReqVo);
            }
            meterCollectReqVo.getMeterIdList().add(meter.getId());
            meterCollectReqVo.getMeterKeyList().add(meter.getMeterKey());
            meter.setLoss(meter.getLoss());//线损
            meter.setPrice(price);//单价
            meter.setPrecision(precision); //计费精度
            meter.setRoundModal(roundMode);
            meterCollectReqVo.getMeterMap().put(meter.getMeterKey(), meter);
        }
        ArrayList<MeterChargeInfo> meterChangeInfos = new ArrayList<>();
        //存储读数
        for (Map.Entry<String, MeterCollectReqVo> mcrq : gatewayMap.entrySet()) {
            try{
                MeterCollectReqVo value = mcrq.getValue();
                if (value.getMeterKeyList().size() > 0) {
                    List<MeterRead> nowMeterReadList = new ArrayList<MeterRead>();
                    List<MeterCollectInfoDto> collectNowList = meterIotService.getCollectInfo(StringUtils.join(value.getMeterKeyList(), ","),null,value.getRequestUrl() , value.getIotType());
                    if (collectNowList == null || collectNowList.size() <= 0){
                        resMsg.append(StringUtils.join(value.getMeterKeyList())).append("读表失败");
                        continue;
                    }
                    //获取最新的一条 水电表 读数信息   负数的情况
                    List<MeterRead> preMeterReadList = meterReadService.findLastMeterReads(value.getMeterIdList());
                    Map<String, MeterRead> preMeterReadMap = new HashMap<String, MeterRead>();
                    for (MeterRead preRead : preMeterReadList) {
                        preMeterReadMap.put(preRead.getMeterKey(), preRead);
                    }
                    for (MeterCollectInfoDto meterRead : collectNowList) {
                        MeterRead nowRead = new MeterRead();
                        MeterRead preRead = preMeterReadMap.get(meterRead.getMeterKey());
                        Meter priceInfo = value.getMeterMap().get(meterRead.getMeterKey());
                        if (priceInfo == null) {//没有配置单价线损，信息有误
                            continue;
                        }
                        //本次最新读数
                        BigDecimal compareTotalUse = BigDecimal.ZERO;
                        BigDecimal nowTotalUse = meterRead.getTotalUse() == null? BigDecimal.ZERO:new BigDecimal(meterRead.getTotalUse());
                        compareTotalUse = nowTotalUse.setScale(0,BigDecimal.ROUND_DOWN); //向下取整
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        if(compareTotalUse.compareTo(BigDecimal.ZERO) < 0){ //读数小于0 忽略
                              continue;
                        }
                       BigDecimal bigRate = new BigDecimal(priceInfo.getRate());  //倍率
                        if (preRead == null){
                            nowRead.setMeterId(priceInfo.getId());
                            nowRead.setTenantId(priceInfo.getTenantId());
                            nowRead.setPrice(priceInfo.getPrice().toString());
                            nowRead.setPrecision(priceInfo.getPrecision());
                            nowRead.setLoss(priceInfo.getLoss().toString());
                            nowRead.setRate(priceInfo.getRate());
                            nowRead.setReadTime(sdf.parse(meterRead.getReadTime()));
                            BigDecimal preTotalUse = priceInfo.getBeginUse() == null ? BigDecimal.ZERO: new BigDecimal(priceInfo.getBeginUse());
                            nowRead.setPreRead(preTotalUse.toString());
                            nowRead.setNowRead(nowTotalUse.toString());
                            nowRead.setNowUse((nowTotalUse.subtract(preTotalUse)).multiply(bigRate).toString());
                            nowRead.setCloseStatus(MeterDeductStatusEnum.METER_DEDUCT_STATUS_OK.getCode());
                            nowRead.setIsBegin(MeterBeginStatusEnum.METER_DEDUCT_BEGIN_YES.getCode());
                            nowMeterReadList.add(nowRead);
                        }else {
                            BigDecimal preTotalUse = preRead.getNowRead() == null ? BigDecimal.ZERO: new BigDecimal(preRead.getNowRead());
                            BigDecimal compareToPreTotalUse = nowTotalUse.setScale(0,BigDecimal.ROUND_DOWN);
                            if (compareTotalUse.compareTo(compareToPreTotalUse) >= 0 ){
                                nowRead.setId(String.valueOf(IdWorker.getId()));
                                nowRead.setMeterId(preRead.getMeterId());
                                nowRead.setTenantId(preRead.getTenantId());
                                nowRead.setCloseStatus(MeterDeductStatusEnum.METER_DEDUCT_STATUS_OK.getCode());
                                nowRead.setPreRead(preRead.getNowRead());
                                nowRead.setNowRead(nowTotalUse.toString());
                                nowRead.setNowUse((nowTotalUse.subtract(preTotalUse)).multiply(bigRate).toString());
                                nowRead.setLoss(priceInfo.getLoss().toString());
                                nowRead.setRate(priceInfo.getRate());
                                nowRead.setPrice(priceInfo.getPrice().toString());
                                nowRead.setPrecision(priceInfo.getPrecision());
                                nowRead.setReadTime(sdf.parse(meterRead.getReadTime()));
                                nowRead.setIsBegin(MeterBeginStatusEnum.METER_DEDUCT_BEGIN_NOT.getCode());
                                nowMeterReadList.add(nowRead);
                            } /*else {
                                //未变化 当前总读数 = 历史总读数
                                resMsg.append(preRead.getMeterKey()).append("读数无变化</br>");
                                continue;
                            }*/
                        }
                        if (null != nowRead && StringUtils.isNotBlank(nowRead.getNowUse()) && new BigDecimal(nowRead.getNowUse()).compareTo(BigDecimal.ZERO) >= 0 ){
                            log.info("数据+{}",nowRead);
                            //构造扣费明细
                            BigDecimal price = StringUtils.isEmpty(nowRead.getPrice()) ? BigDecimal.ZERO: new BigDecimal(nowRead.getPrice());
                            BigDecimal loss =  StringUtils.isEmpty(nowRead.getLoss())? BigDecimal.ONE: new BigDecimal(nowRead.getLoss());
                            BigDecimal nowUse = StringUtils.isEmpty(nowRead.getNowUse()) ? BigDecimal.ZERO: new BigDecimal(nowRead.getNowUse());
                            BigDecimal amount = nowUse.multiply(price)/*.multiply(rate)*/.multiply(loss);
                            amount = BigDecimal.ZERO.subtract(amount);
                            MeterChargeInfo meterCharge = new MeterChargeInfo();
                            meterCharge.setChargeAmount(amount.setScale(nowRead.getPrecision(),priceInfo.getRoundModal()).toString());
                            log.info("精度{}"+nowRead.getPrecision());
                            meterCharge.setTenantId(nowRead.getTenantId());
                            meterCharge.setPrecision(nowRead.getPrecision());
                            meterCharge.setChargeType(MeterChargeTypeEnum.METER_CHARGE_TYPE_DOCK.getCode());
                            meterCharge.setChargeTime(new Date());
                            meterCharge.setMeterId(priceInfo.getId());
                            meterCharge.setChargeStatus(MeterChargeStatusEnum.METER_CHARGE_STATUS_OK.getCode());
                            meterCharge.setTotalUse(nowRead.getNowRead());
                            meterCharge.setChargeUse(nowUse.toString());
                            meterCharge.setReadTime(nowRead.getReadTime());
                            meterCharge.setPaymentStatus(PayStatusEnum.PAY_STATUS_YES.getCode());
                            meterCharge.setRound(priceInfo.getRoundModal());
                            meterCharge.setMeterReadId(nowRead.getId());
                           // meterCharge.setTenantId(priceInfo.getTenantId());
                            meterChangeInfos.add(meterCharge);
                        }
                    }
                    if (nowMeterReadList.size() >0 ){
                        meterReadService.saveBatch(nowMeterReadList);
                    }
                    List<MeterChargeRespVo> meterChargeRespVoList = new ArrayList<>();
                     if (meterChangeInfos.size() > 0 ){
                        meterChargeInfoService.saveBatch(meterChangeInfos);
                        meterChangeInfos.forEach(temp->{
                            MeterChargeRespVo meterChargeRespVo = new MeterChargeRespVo();
                            BeanUtils.copyProperties(temp,meterChargeRespVo);
                            meterChargeRespVoList.add(meterChargeRespVo);
                        });
                        meterChargeInfoService.refreshRemainByPay(meterChargeRespVoList,"手动读表",MeterChargeTypeEnum.METER_CHARGE_TYPE_DOCK.getCode());
                    }

                }
            }catch (Exception e){
                throw new RuntimeException("读取仪表设备异常",e);
            }
        }
        if (resMsg.length() > 0){
            if (meterChangeInfos.size() > 0 ){
                resMsg.append("以外的表读取成功");
            }
            return Result.ok(resMsg.toString());
        }
        if (meterChangeInfos.size() == 0 ){
            return Result.ok("读表无变化");
        }
        return Result.ok(meterChangeInfos);
    }

    @AutoLog(value = "仪表信息同步到硬件平台")
    @ApiOperation(value = "仪表信息同步到硬件平台", notes = "仪表信息同步到硬件平台")
    @PostMapping(value = "/syncMeterToPlatform")
    public Result<String> syncMeterToPlatform(@RequestParam(name = "ids", required = true) String ids) {
        log.info("仪表信息同步到硬件平台接受信息:{}",ids);
        if (ids == null || "".equals(ids.trim())) {
            return Result.error("参数不识别");
        }
        List<Meter> meterList = meterService.findByIds(Arrays.asList(ids.split(",")));
        StringBuilder sb  = new StringBuilder();
        StringBuilder su = new StringBuilder();
        for (Meter meter:meterList){
            if (StringUtils.isBlank(meter.getMeterCode())){
                sb.append(meter.getMeterCode()).append(":仪表编号为空！");
                continue;
            }
            if (StringUtils.isBlank(meter.getMeterGateway())){
                sb.append(meter.getMeterCode()).append(":未设置网关！");
                continue;
            }
            if (StringUtils.isBlank(meter.getCollectorAddress())){
                sb.append(meter.getMeterCode()).append(":未设置采集器地址！");
                continue;
            }
            MeterGateway meterGateway = meterGatewayService.getById(meter.getMeterGateway());
            if (meterGateway == null || meterGateway.getIsUse() == 1){
                sb.append(meter.getMeterCode()).append(":设置的网关不存在或已被禁用！");
                continue;
            }
            MeterBaseDto meterBaseDto = meterIotService.saveMeterBase(meter.getMeterKey(),meter.getMeterCode(),meter.getCollectorAddress(),meter.getMeterType(),"",meterGateway.getRequestUrl(),meterGateway.getIotType());
            if (meterBaseDto != null){
                //更新同步状态
                meterService.updateSyncStatus(meter.getId(),meterBaseDto.getMeterKey());
                su.append(meter.getMeterCode()).append(":").append("同步成功");
            } else {
                sb.append(meter.getMeterCode()).append(":").append("同步失败");
            }
        }
        if (StringUtils.isNotBlank(sb.toString())){
            return Result.error(sb.toString());
        }
        return Result.ok(su.toString());
    }


    /**
     * 编辑
     */
    @RequestMapping("edit")
    public Result edit(@RequestBody Map<String,Object> map){
        Result<Object> result = new Result<>();
        Meter meter = JSON.parseObject(JSON.toJSONString(map), Meter.class);
        try {
            boolean b = meterService.editMeter(meter);
            result.setMessage("修改成功");
            result.setSuccess(b);
          }catch (Exception e){
            result.setMessage("修改失败");
              e.printStackTrace();
          }
        return  result;
    }
    /**
     * 换表
     */
    @RequestMapping("changeMeter")
    public Result<?> changeMeter(@RequestBody Meter meter){
        Result<Object> result = new Result<>();
        try {

            Integer integer = meterService.changeMeter(meter);
            result.setSuccess(integer>0?true:false);
        }catch (Exception e){
            e.printStackTrace();
            return Result.error("操作失败");
        }
       return result;
    }
    @RequestMapping(value = "/importMeterBasicExcel", method = RequestMethod.POST)
    public Result<?> importMeterBasicExcel(HttpServletRequest request, HttpServletResponse response ,@RequestParam("projectId")String projectId) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();// 获取上传文件对象
            ImportParams params = new ImportParams();
            params.setNeedSave(false);
            try {
                int successNum = 0;
                int failureNum = 0;
                int row = 1;
                StringBuilder failureMsg = new StringBuilder();
                List<Meter> listMeters = ExcelImportUtil.importExcel(file.getInputStream(), Meter.class, params);
                List<Meter> newMeterList = Lists.newArrayList();
                if (listMeters != null && listMeters.size() > 0) {
                    ArrayList<Meter> collect = listMeters.stream()
                            .collect(Collectors.collectingAndThen(
                                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getMeterCode()  ))),
                                    ArrayList::new));
                    if ( collect.size() < listMeters.size()){
                        return Result.error("文件中存在相同的设备编号");
                    }
                    for (Meter meter:listMeters){
                       if (StringUtils.isEmpty(meter.getProjectName())){
                           failureMsg.append("<br/>第").append(row).append("行：请输入项目名称; ");
                           failureNum++;
                           row++;
                           continue;
                       }else {
                            //查询项目名字是否与ID一致
                            String projectName = meterService.queryProjectName(projectId);
                            String tenantId = meterService.queryTenantId(projectId);
                            if (projectName.equals(meter.getProjectName().trim())){
                                meter.setProjectName(meter.getProjectName());
                                meter.setProjectId(projectId);
                                if (meter.getMeterAddressAddVo() == null){
                                    MeterAddressAddVo meterAddReqVo = new MeterAddressAddVo();
                                    meterAddReqVo.setProjectId(projectId);
                                    meterAddReqVo.setTenantId(tenantId);
                                    meter.setMeterAddressAddVo(meterAddReqVo);
                                }
                            }else {
                                failureMsg.append("<br/>第").append(row).append("行：请输入与选择项目一直的名称; ");
                                failureNum++;
                                row++;
                                continue;
                            }
                        }
                       if(StringUtils.isNotEmpty(meter.getFloorName())  ){
                           //查询楼宇ID 依据项目ID，楼宇名称
                               String floorId = meterService.queryFloorName(projectId, meter.getFloorName().trim());
                               if (StringUtils.isEmpty(floorId)){
                                   failureMsg.append("<br/>第").append(row).append("行：请输入正确的楼宇名称; ");
                                   failureNum++;
                                   row++;
                                   continue;
                               }
                               meter.getMeterAddressAddVo().setFloorId(floorId);
                               if (StringUtils.isNotEmpty(meter.getRoomName())){
                                   String strRoomName =meter.getRoomName().trim();
                                   if (meter.getRoomName().trim().contains(".0")){
                                        strRoomName = meter.getRoomName().trim().substring(0, meter.getRoomName().indexOf("."));
                                   }
                                   String roomId = meterService.queryRoomName(floorId,strRoomName);
                                   if (StringUtils.isEmpty(roomId)){
                                       failureMsg.append("<br/>第").append(row).append("行：请输入正确的房间名称; ");
                                       failureNum++;
                                       row++;
                                       continue;
                                   }
                                   meter.getMeterAddressAddVo().setRoomId(roomId);
                               }
                       }
                       if (StringUtils.isNotEmpty(meter.getMeterCode()) && StringUtils.isNotEmpty(meter.getMeterGateway())){
                              String strGateWay = meter.getMeterGateway().trim();
                            if (strGateWay.contains(".")){
                                  strGateWay=meter.getMeterGateway().substring(0, strGateWay.indexOf("."));
                            }
                           String gateWayId =meterGatewayService.queryMeterGateWayName(projectId,strGateWay);
                            if (StringUtils.isNotEmpty(gateWayId)){
                                Integer count = meterGatewayService.queryCountByWayNo(meter.getMeterCode().trim(),gateWayId );
                                if (count > 0){
                                    failureMsg.append("<br/>第").append(row).append("行：该设备编号已配置; ");
                                    failureNum++;
                                    row++;
                                    continue;
                                }else {
                                    meter.setMeterCode(meter.getMeterCode().trim());
                                    meter.setMeterGateway(gateWayId);
                                }
                            }else {
                                failureMsg.append("<br/>第").append(row).append("行：请输入正确的网关名称; ");
                                failureNum++;
                                row++;
                                continue;
                            }
                       }else {
                           failureMsg.append("<br/>第").append(row).append("行：请填写网关或者设备编号; ");
                           failureNum++;
                           row++;
                           continue;
                       }
                       if (StringUtils.isNotEmpty(meter.getCollectorAddress())){
                           meter.setCollectorAddress(meter.getCollectorAddress().trim());
                       }
                       Pattern pattern = Pattern.compile("[0-9]*");
                       Integer rate = meter.getRate() == null ? null : meter.getRate();
                       if(null == rate){
                           failureMsg.append("<br/>第").append(row).append("行：请输入仪表倍率(正整数);");
                           failureNum++;
                           row++;
                           continue;
                       }

                       if (StringUtils.isNotEmpty(meter.getBeginAmount().trim())){
                           if (meter.getBeginAmount().contains(".0")){
                               Integer i = new Double(meter.getBeginAmount().trim()).intValue();
                               meter.setBeginAmount(String.valueOf(i));
                           }else {
                               failureMsg.append("<br/>第").append(row).append("行： 仪表初始金额为(正整数);");
                               failureNum++;
                               row++;
                               continue;
                           }
                       }else {
                           failureMsg.append("<br/>第").append(row).append("行：请输入仪表初始金额(正整数);");
                           failureNum++;
                           row++;
                           continue;
                       }
                       if (StringUtils.isNotEmpty(meter.getBeginUse().trim())){
                           if (!meter.getBeginUse().contains(".0")){
                               failureMsg.append("<br/>第").append(row).append("行： 初始用量为整数");
                               failureNum++;
                               row++;
                               continue;
                           } else {
                               Integer i = new Double(meter.getBeginUse().trim()).intValue();
                               meter.setBeginAmount(String.valueOf(i));
                           }
                       }else {
                           failureMsg.append("<br/>第").append(row).append("行： 请输入初始用量");
                           failureNum++;
                           row++;
                           continue;
                       }
                       if (StringUtils.isNotEmpty(meter.getLoss().trim())){
                          meter.setLoss(meter.getLoss().trim());
                       }
                       if (StringUtils.isNotEmpty(meter.getMType().trim())){
                           if (meter.getMType().trim().equals("电表")){
                               meter.setMeterType(1);
                           }else {
                               meter.setMeterType(2);
                           }
                       }else {
                           failureMsg.append("<br/>第").append(row).append("行： 请输入表类型");
                           failureNum++;
                           row++;
                           continue;
                       }
                       if (null == meter.getLoss()){
                           meter.setLoss("1");
                       }
                       if(null == meter.getSwitchUse()){
                           meter.setSwitchStatus(0);
                       }
                       if(null == meter.getWarningUse()){
                           failureMsg.append("<br/>第").append(row).append("行： 请输入预警用量");
                           failureNum++;
                           row++;
                           continue;
                       }
                    if (StringUtils.isNotEmpty(meter.getMeterFee().trim())){
                        List<String> payItems = meterFeeRuleService.queryIdByname(Arrays.asList(meter.getMeterFee().split(",")), projectId);
                        if (payItems.size() > 0){
                             meter.setPayItem(payItems);
                        }else {
                            failureMsg.append("<br/>第").append(row).append("行： 请填写该项目已配置的收费项");
                            failureNum++;
                            row++;
                            continue;
                        }
                    }else {
                        failureMsg.append("<br/>第").append(row).append("行： 请输入收费项");
                        failureNum++;
                        row++;
                        continue;
                    }

                       row++;
                       newMeterList.add(meter);
                   }
                   meterService.saveBatchExcel(newMeterList);
                    if (failureNum > 0) {
                        failureMsg.insert(0, "，失败 " + failureNum + " 条电表，导入信息如下：");
                    }
                }
                return Result.error("导入电表基础信息失败！Excel数据为空");
            } catch (Exception e) {
                log.error("仪表基础信息导入异常:{}",e);
            }finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.ok("导入电表基础信息失败！");
    }
    /**
     * 删除
     */
    @RequestMapping("delete")
    public Result<?> delete(@RequestParam("id")String id){
        Result<Object> result = new Result<>();
        try {
            boolean b = meterService.removeById(id);
            result.setSuccess(b);
            result.setResult("删除成功");
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 通断记录
     * meterId
     */
    @RequestMapping("getSwitchRecord")
    public Result<List<MeterSwitchRespVo>> getSwitchRecord(@RequestParam("meterId")String meterId){
        Result<List<MeterSwitchRespVo>> result = new Result<>();
         if (StringUtils.isEmpty(meterId)){
             return Result.error("未找到对应的实体");
         }
         try {
             List<MeterSwitchRespVo> switchRecord = meterControlSwitchService.getSwitchRecord(meterId);
             result.setSuccess(true);
             result.setResult(switchRecord);
          }catch (Exception e){
             e.printStackTrace();
             return Result.error("请求错误");
         }
        return result;
    }
    /**
     * 获取楼宇，房间
     * param (projectId)
     */
    @RequestMapping("getFloorAndRoomList")
    public Result<?> getFloorAndRoomList(@RequestParam("projectId")String projectId){
        Result<Object> result = new Result<>();
        List<roomResVo> roomResVoList = meterService.queryRoomList(projectId);
        List<FloorResVo> floorResVoList = meterService.queryFloorList(projectId);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("roomResVoList",roomResVoList);
        hashMap.put("floorResVoList",floorResVoList);
        result.setResult( hashMap);

       return result;
    }

    /**
     * 批量修改采集器编号
     */
   @RequestMapping("updateAddress")
    public Result<?> updateAddress(@RequestParam("meterIds")String meterIds,
                                   @RequestParam("cars")String collectorAddress){
       Result<Object> result = new Result<>();
       //循环list 如果采集器选择不一致拒绝修改
       if (null == meterIds){
           return Result.error("系统错误,请联系管理员");
       }
       List<String> meterIdsList = Arrays.asList(meterIds.split(";"));
       //查询所选表的采集器编号是否一致
       List<String> meterCollectorList = meterService.getCollectorAddress(meterIdsList);
       if (meterCollectorList.size() > 1){
           boolean flag = hasSame(meterCollectorList);
           if ( !flag ){
               return Result.error("请选择采集器一致的进行修改");
           }
       }
       try {
           meterService.collectorAddressBatch(meterIdsList,collectorAddress);
           //同步
           Result<String> stringResult = syncMeterToPlatform(StringUtils.join(meterIdsList.toArray(), ","));
           result.setSuccess(true);
           result.setMessage("修改成功");
       }catch (Exception e){
           result.setMessage("修改失败");
       }
      return result;
   }
    private   boolean hasSame(List<? extends Object> list) {
        if(null == list) return false;
        return 1 == new HashSet<Object>(list).size();
    }

    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(Meter meter,HttpServletRequest request, HttpServletResponse response) {
       LoginUser user = SsoUtil.getLoginUser();
       meter.setTenantId(user.getTenantId());
        // Step.1 组装查询条件
        //Step.2 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        meter.setSqlMap( sysUserRoleService.dataScopeProjectOnlyFilter(SsoUtil.getLoginUser(), "p", meter.getMenuPath(), null, meter.getDepartIdEx()));
        List<Meter> pageList = meterService.findPage(null,meter);
        log.info("数据",pageList);
        ArrayList<ExportMeterVo> objects = Lists.newArrayList();
        for (Meter temp:pageList){
            ExportMeterVo exportMeterVo = new ExportMeterVo();
            BeanUtils.copyProperties(temp,exportMeterVo);
            String gateWayName = meterGatewayService.queryMeterGateWayName(temp.getProjectId(), temp.getMeterGateway());
            exportMeterVo.setMeterGatewayName(gateWayName);
            List<String> feeNameList = meterService.queryFeeItemNameByMeterId(temp.getId());
            String strFeeName= "";
            for (String stt :feeNameList){
                strFeeName = strFeeName+stt+"\n";
            }
            exportMeterVo.setMeterFee(strFeeName);
            List<ReceiveList> addressList = meterService.getAddressList(temp.getId());
            StringBuilder str = new StringBuilder();
            for (ReceiveList receiveList:addressList){
                if(receiveList != null){
                    str.append(receiveList.getFName()).append(receiveList.getRName()).append("\n");
                }
            }
            exportMeterVo.setAddress(str.toString());
            objects.add(exportMeterVo);
        }
        //导出文件名称
        mv.addObject(NormalExcelConstants.FILE_NAME, "仪表基础信息" + DateUtils.date2Str(new Date(),DateUtils.yyyyMMdd));
        mv.addObject(NormalExcelConstants.CLASS, ExportMeterVo.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("仪表基础信息数据", "导出人:"+user.getRealname(), "导出信息"));
        mv.addObject(NormalExcelConstants.DATA_LIST, objects);
        return mv;
    }
    /**
     * 仪表充值缴费记录
     */
    @RequestMapping("getMeterPayRecord")
    public Result<List<MeterChargeInfo>> getMeterPayRecord(@RequestParam("meterId")String meterId){
        Result<List<MeterChargeInfo>> objectResult = new Result<>();
        List<MeterChargeInfo> payrecordList = meterService.getMeterPayRecord(meterId);
        objectResult.setResult(payrecordList);
        return objectResult;

    }
}
